<template>
  <div style="position: relative;display: flex;width:100%;height:100%;flex-direction: row">
    <div style="width:220px;height:100%;flex-grow: 0;flex-shrink:0;">
      <el-collapse>
        <el-collapse-item title="基础控件">
          <div v-for="(t,index) of componentTypeList" :key="index"
               style="width:80px;height:110px;display:inline-block">
            <div draggable="true"
                 style="border:0px #ccc solid;width:80px;height:80px;border-radius:12px;overflow: hidden;"
                 @dragstart="handleSourceDragstart($event,t,'component')"
            >
              <component :is="components[t.type].view" :option="t.placeHolderOption"></component>
            </div>
            <div style="text-align: center;">{{ t.label }}</div>
          </div>
        </el-collapse-item>
        <el-collapse-item title="模板">
          <div v-for="(t,index) of templateList" :key="index" style="width:80px;height:110px;display:inline-block;margin-left:5px;">
            <div draggable="true"
                 style="border:1px #ccc solid;width:80px;height:80px;border-radius:12px;overflow: hidden;"
                 @dragstart="handleSourceDragstart($event,t,'template')"
            >
              <component :is="components[t.componentType].view" :option="t.option.option"></component>
            </div>
            <div style="text-align: center;">{{ t.name }}</div>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
    <div style="flex-grow: 1;display: flex;flex-direction: column;">
      <div style="flex-grow: 0;flex-shrink: 0;height:60px;width:100%;">
        <el-form :inline="true">
          <el-form-item label="画板宽度">
            <el-input-number :min="300" :step="1" v-model="paperWidth"></el-input-number>
          </el-form-item>
          <el-form-item label="画板高度">
            <el-input-number :min="300" :step="1" v-model="paperHeight"></el-input-number>
          </el-form-item>
          <el-form-item label="放大倍率">
            <el-input-number :min="0.1" :step="0.1" :max="5" v-model="zoom"></el-input-number>
            <!--            <el-select v-model="zoom" @change="handleZoomChange">-->
            <!--              &lt;!&ndash;              <el-option label="10%" :value="0.1"></el-option>&ndash;&gt;-->
            <!--              <el-option label="25%" :value="0.25"></el-option>-->
            <!--              <el-option label="33%" :value="0.33"></el-option>-->
            <!--              <el-option label="50%" :value="0.5"></el-option>-->
            <!--              <el-option label="75%" :value="0.75"></el-option>-->
            <!--              <el-option label="100%" :value="1"></el-option>-->
            <!--              <el-option label="125%" :value="1.25"></el-option>-->
            <!--              <el-option label="150%" :value="1.5"></el-option>-->
            <!--              <el-option label="175%" :value="1.75"></el-option>-->
            <!--              <el-option label="200%" :value="2"></el-option>-->
            <!--              <el-option label="250%" :value="2.5"></el-option>-->
            <!--              <el-option label="300%" :value="3"></el-option>-->
            <!--              <el-option label="500%" :value="5"></el-option>-->
            <!--            </el-select>-->
          </el-form-item>
          <el-form-item>
            <el-button @click="handle2center">居中</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div style="flex-grow: 1;border:1px #ccc solid;width:100%;">
        <drag_panel ref="dragPanelRef"
                    :components="components"
                    @componentSelect="handleComponentSelect"
                    @linkSelect="handleLinkSelect"
        ></drag_panel>
      </div>
    </div>
    <div
        style="flex-grow: 0;flex-shrink:0;width:300px;padding:10px;display: flex;flex-direction: column">
      <template v-if="selectedComponentOption">
        <div style="flex-grow: 1">
          <component :is="selectedComponentOptionView" :co="selectedComponentOption"></component>
        </div>
        <div style="flex-grow: 0">
          <el-button type="primary" @click="handleDelete">删除</el-button>
          <el-button type="primary" @click="handleSaveComponent2Template">保存成模板</el-button>
        </div>
      </template>
      <template v-if="selectedLinkOption!=null">
        <div style="flex-grow: 1">
          <DLinkOption :option="selectedLinkOption"></DLinkOption>
        </div>
        <div style="flex-grow: 0">
          <el-button type="primary" @click="handleDeleteLink">删除</el-button>
        </div>
      </template>
    </div>
  </div>
  <el-dialog
      v-model="templateNameDialogVisible"
      title="请输入模板名字"
      width="30%"
  >
    <el-form>
      <el-form-item label="模板名字">
        <el-input v-model="newTemplateName"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="templateNameDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="saveComponent2Template">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import {nextTick, onMounted, reactive, Ref, ref, shallowRef, UnwrapRef, watch} from "vue";
import {ComponentAnchor, ComponentOption} from "@/components/MPanel/ComponentOption.ts";


import {registerBaseComponent} from "@/components/MPanel/m_component/base/image";
import {registerFlowComponent} from "@/components/MPanel/m_component/flow/index.ts";
import {LinkOption} from "@/components/MPanel/LinkOption.ts";
import image_base64 from "@/views/drag_edit/image_base64.ts";
import templates from "@/components/MPanel/templates.ts";
import {v4 as uuidv4} from 'uuid';
import DLinkOption from "@/components/MPanel/links/link1/MLinkOption.vue";
import {QWebChannel} from "qwebchannel"
import Drag_panel from "@/components/MPanel/drag_panel.vue";
import {ComponentTypeOption} from "@/components/MPanel/ComponentTypeOption.ts";
const components: any = {}
registerBaseComponent(components)
registerFlowComponent(components)
const dragPanelRef: Ref<UnwrapRef<null>> = ref(null);
let zoom = ref(1);
let paperWidth = ref(1000);
let paperHeight = ref(1000);
let componentTypeList: Ref<any> = ref([])
for (let key in components) {
  let c = components[key]
  componentTypeList.value.push({
    label: c.label,
    type: key,
    view: c.view,
    placeHolderOption: c.placeHolderOption,
    initSize: c.initSize
  })
}

//页面上的组件列表
let componentList: Array<ComponentOption> = reactive([]);
//先初始化一个组件
let co: ComponentOption = new ComponentOption("image",null, 500, 500, 150, 120,ComponentTypeOption.getDefault())
co.zIndex = 0
co.id = "1"
co.addDefaultAnchors();
co.option = {
  url: image_base64["ecu_1.png"]
}
componentList.push(co)

//组件模板列表
let templateList: any = reactive(templates);

//被用户选中的组件
let selectedComponentOption: Ref<ComponentOption | null> = ref(null);
//被用户选中的连接线
let selectedLinkOption: Ref<LinkOption | null> = ref(null);
//被选中的组件的配置页面
let selectedComponentOptionView: Ref<any | null> = shallowRef(null);

let linkList: Array<LinkOption> = reactive([]);
onMounted(() => {
  handle2center()
})

//从左边拖动组件或模板到右边
function handleSourceDragstart(event: DragEvent, t: any, sourceType: string) {
  if (event && event.dataTransfer) {
    if (sourceType === 'template') {
      //把模板变成组件
      let data = {
        sourceType: 'template',
        componentType: t.componentType,
        offsetX: event.offsetX,
        offsetY: event.offsetY,
        option: t.option
      }
      event.dataTransfer.setData('data', JSON.stringify(data));
    } else {
      let data = {...t, offsetX: event.offsetX, offsetY: event.offsetY, sourceType: 'component'}
      event.dataTransfer.setData('data', JSON.stringify(data));
    }
  }
}

/**
 * 居中
 */
function handle2center() {
  //获得画布的视野属性，进而获得视野宽度和高度
  dragPanelRef.value.move2center()
}

// let oldZoomValue = zoom.value;
watch(zoom, (nv, ov) => {
  // oldZoomValue = nv;
  //使用户视窗位置不变
  dragPanelRef.value.setZoom(nv);
})
watch([paperWidth, paperHeight], ([nw, nh], [ow, oh]) => {
  dragPanelRef.value.setPagerSize(nw, nh)
})

function handleComponentSelect(componentOption: ComponentOption, optionView: any) {
  selectedComponentOption.value = componentOption;
  selectedComponentOptionView.value = optionView;
}

function handleLinkSelect(linkOption: LinkOption) {
  selectedLinkOption.value = linkOption;
}

function handleDelete() {
  if (selectedComponentOption.value != null) {
    dragPanelRef.value.deleteComponent(selectedComponentOption.value)
  }
}

function handleDeleteLink() {
  if (selectedLinkOption.value != null) {
    dragPanelRef.value.deleteLink(selectedLinkOption.value)
  }
}

const templateNameDialogVisible = ref(false);
const newTemplateName = ref("")

function handleSaveComponent2Template() {
  //提醒用户输入模板名字
  newTemplateName.value = ""
  templateNameDialogVisible.value = true
}

//把选中的组件保存成模板
function saveComponent2Template() {
  let sco: ComponentOption | null = selectedComponentOption.value
  if (!sco) {
    return;
  }
  newTemplateName.value = newTemplateName.value.trim();
  let nt = {
    componentType: sco.type,
    templateId: uuidv4(),
    name: newTemplateName.value,
    option: {
      w: sco.w,
      h: sco.h,
      type: sco.type,
      anchors: [],
      option: JSON.parse(JSON.stringify(sco.option)),
    }
  };
  for (let anchor of sco.anchors) {
    nt.option.anchors.push({px: anchor.px, py: anchor.py})
  }
  //如果名字重复，直接覆盖同名的
  let has = false;
  for (let index = 0; index < templateList.length; index++) {
    let template = templateList[index];
    if (template.name === nt.name) {
      has = true
      templateList.splice(index, 1, nt);
      break;
    }
  }
  if (!has) {
    templateList.push(nt);
  }
  templateNameDialogVisible.value = false
}
</script>
